package net.maku.member.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fhs.trans.service.impl.TransService;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import lombok.AllArgsConstructor;
import net.maku.framework.common.constant.Constant;
import net.maku.framework.common.excel.ExcelFinishCallBack;
import net.maku.framework.common.utils.ExcelUtils;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.mybatis.service.impl.BaseServiceImpl;
import net.maku.framework.security.user.SecurityUser;
import net.maku.member.convert.MemberUserConvert;
import net.maku.member.dao.MemberEducationalBackgroundDao;
import net.maku.member.dao.MemberTagDao;
import net.maku.member.entity.MemberEducationalBackgroundEntity;
import net.maku.member.entity.MemberUserEntity;
import net.maku.member.entity.MemberUserTransferEntity;
import net.maku.member.query.MemberUserQuery;
import net.maku.member.service.MemberUserTransferService;
import net.maku.member.vo.*;
import net.maku.member.dao.MemberUserDao;
import net.maku.member.service.MemberUserService;
import net.maku.system.dao.SysOrgDao;
import net.maku.system.entity.SysOrgEntity;
import net.maku.system.enums.ShiftEnum;
import net.maku.system.service.SysOrgService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 会员信息
 *
 * @author 阿沐 babamu@126.com
 * @since 1.0.0 2025-03-15
 */
@Service
@AllArgsConstructor
public class MemberUserServiceImpl extends BaseServiceImpl<MemberUserDao, MemberUserEntity> implements MemberUserService {
    private final MemberUserDao memberUserDao;
    private final MemberTagDao memberTagDao;
    private final MemberEducationalBackgroundDao educationalBackgroundDao;
    private final MemberUserTransferService memberUserTransferService;
    private final TransService transService;
    private final PasswordEncoder passwordEncoder;
    private final SysOrgDao sysOrgDao;
    private final SysOrgService sysOrgService;

    @Override
    public PageResult<MemberUserVO> page(MemberUserQuery query) {
        query.setAuditStatus(1);
        query.setRemoveStatus(0);
        IPage<MemberUserEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));
        List<MemberUserVO> reuslt = BeanUtil.copyToList(page.getRecords(), MemberUserVO.class);
        setMemberTags(reuslt);
        return new PageResult<>(reuslt, page.getTotal());
    }

    /**
     * 设置tag
     *
     * @param memberUserVOList 结果
     */
    private void setMemberTags(List<? extends MemberUserVO> memberUserVOList) {
        if (CollectionUtils.isNotEmpty(memberUserVOList)) {
            List<Long> tagIdList = memberUserVOList.stream().filter(item -> CollectionUtils.isNotEmpty(item.getMemberTags())).map(MemberUserVO::getMemberTags).flatMap(Collection::stream).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(tagIdList)) {
                return;
            }
            List<MemberTagVO> memberTagVOList = BeanUtil.copyToList(memberTagDao.selectBatchIds(tagIdList), MemberTagVO.class);
            if (CollectionUtils.isNotEmpty(memberTagVOList)) {
                Map<Long, MemberTagVO> memberTagVOMap = memberTagVOList.stream().collect(Collectors.toMap(MemberTagVO::getId, Function.identity()));
                memberUserVOList.forEach(item -> {
                    if (CollectionUtils.isNotEmpty(item.getMemberTags())) {
                        List<MemberTagVO> memberTagVOS = new ArrayList<>();
                        item.getMemberTags().forEach(tagItem -> {
                            if (ObjectUtils.isNotEmpty(memberTagVOMap.get(tagItem))) {
                                memberTagVOS.add(memberTagVOMap.get(tagItem));
                            }
                        });
                        item.setMemberTagVOList(memberTagVOS);
                    }
                });
            }
        }
    }


    @Override
    public PageResult<MemberUserVO> pageByConditions(MemberUserQuery query) {
        LambdaQueryWrapper<MemberUserEntity> wrapper = getWrapper(query);
        IPage<MemberUserEntity> page = baseMapper.selectPage(getPage(query), wrapper);
        List<MemberUserVO> reuslt = BeanUtil.copyToList(page.getRecords(), MemberUserVO.class);
        setMemberTags(reuslt);
        return new PageResult<>(reuslt, page.getTotal());
    }

    @Override
    public PageResult<MemberUserTransferVO> pageTransfer(MemberUserQuery query) {
        List<MemberUserTransferVO> reuslt = new ArrayList<>();
        IPage<MemberUserTransferEntity> page = memberUserTransferService.getMemberUserTransfer(new Page<>(query.getPage(), query.getLimit()));
        if (CollectionUtils.isNotEmpty(page.getRecords())) {
            Map<Long, MemberUserTransferEntity> transferMap = page.getRecords().stream().collect(Collectors.toMap(MemberUserTransferEntity::getMemberUserId, Function.identity()));
            query.setMemberIdList(page.getRecords().stream().map(MemberUserTransferEntity::getMemberUserId).collect(Collectors.toList()));
            LambdaQueryWrapper<MemberUserEntity> wrapper = getWrapper(query);
            List<MemberUserEntity> memberUserEntityList = baseMapper.selectList(wrapper);
            reuslt = BeanUtil.copyToList(memberUserEntityList, MemberUserTransferVO.class);
            reuslt.forEach(item -> {
                MemberUserTransferEntity transferEntity = transferMap.get(item.getId());
                item.setTransferOrgId(transferEntity.getTransferOrgId());
                item.setNowOrgId(transferEntity.getNowOrgId());
                item.setTransId(transferEntity.getId());
            });
        }
        setMemberTags(reuslt);
        return new PageResult<>(reuslt, page.getTotal());
    }

    @Override
    public void shiftIn(Long id) {
        shiftMemberUser(id, ShiftEnum.SHIFT_IN.getValue());
    }

    /**
     * 会员用户移入移出
     *
     * @param id    主键
     * @param shift 标识
     */
    private void shiftMemberUser(Long id, Integer shift) {
        MemberUserEntity memberUserEntity = new MemberUserEntity();
        memberUserEntity.setId(id);
        memberUserEntity.setRemoveStatus(shift);
        this.baseMapper.updateById(memberUserEntity);
    }

    @Override
    public void shiftOut(Long id) {
        shiftMemberUser(id, ShiftEnum.SHIFT_OUT.getValue());
    }

    /**
     * 构造查询条件
     *
     * @param query 查询条件
     * @return 构造器
     */
    private LambdaQueryWrapper<MemberUserEntity> getWrapper(MemberUserQuery query) {
        LambdaQueryWrapper<MemberUserEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotEmpty(query.getRealName()), MemberUserEntity::getRealName, query.getRealName()).eq(ObjectUtils.isNotEmpty(query.getEducationalBackground()), MemberUserEntity::getEducationalBackground, query.getEducationalBackground())
                .eq(ObjectUtils.isNotEmpty(query.getPoliticalStatus()), MemberUserEntity::getPoliticalStatus, query.getPoliticalStatus())
                .eq(ObjectUtils.isNotEmpty(query.getAuditStatus()), MemberUserEntity::getAuditStatus, query.getAuditStatus())
                .eq(ObjectUtils.isNotEmpty(query.getRemoveStatus()), MemberUserEntity::getRemoveStatus, query.getRemoveStatus())
                .like(StringUtils.isNotEmpty(query.getMobile()), MemberUserEntity::getMobile, query.getMobile())
                .eq(MemberUserEntity::getWhetherMember, query.getWhetherMember())
                .in(CollectionUtils.isNotEmpty(query.getMemberIdList()), MemberUserEntity::getId, query.getMemberIdList());
        if (ObjectUtils.isNotEmpty(query.getOrgId())) {
            wrapper.in(MemberUserEntity::getOrgId, sysOrgService.getSubOrgIdList(query.getOrgId()));
        } else {
            dataScopeWrapper(wrapper);
        }
        return wrapper.orderByDesc(MemberUserEntity::getId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(MemberUserVO vo) {
        if (ObjectUtils.isNotEmpty(this.getOne(new LambdaQueryWrapper<MemberUserEntity>().eq(MemberUserEntity::getMobile, vo.getMobile())))) {
            throw new RuntimeException("该手机号已存在");
        }
        MemberUserEntity entity = MemberUserConvert.INSTANCE.convert(vo);
        entity.setPassword(passwordEncoder.encode("123456"));
        entity.setWhetherMember(Constant.ENABLE);
        baseMapper.insert(entity);
        insert(vo.getMemberEducationalBackgroundVOList(), entity.getId());
    }

    private void insert(List<MemberEducationalBackgroundVO> memberEducationalBackgroundVOList, Long memberUserId) {
        List<MemberEducationalBackgroundEntity> educationalBackgroundEntityList = BeanUtil.copyToList(memberEducationalBackgroundVOList, MemberEducationalBackgroundEntity.class);
        educationalBackgroundEntityList.forEach(item -> {
            item.setId(null);
            item.setMemberUserId(memberUserId);
            educationalBackgroundDao.insert(item);
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(MemberUserVO vo) {
        MemberUserEntity checkEntity = this.getOne(new LambdaQueryWrapper<MemberUserEntity>().eq(MemberUserEntity::getMobile, vo.getMobile()));
        if (ObjectUtils.isNotEmpty(checkEntity) && !checkEntity.getId().equals(vo.getId())) {
            throw new RuntimeException("该手机号已存在");
        }
        MemberUserEntity entity = MemberUserConvert.INSTANCE.convert(vo);
        entity.setPassword(null);
        updateById(entity);
        educationalBackgroundDao.delete(new LambdaQueryWrapper<MemberEducationalBackgroundEntity>().eq(MemberEducationalBackgroundEntity::getMemberUserId, vo.getId()));
        insert(vo.getMemberEducationalBackgroundVOList(), vo.getId());
    }

    @Override
    public MemberUserVO getInfo(Long id) {
        MemberUserVO memberUserVO = BeanUtil.copyProperties(this.getById(id), MemberUserVO.class);
        if (CollectionUtils.isNotEmpty(memberUserVO.getMemberTags())) {
            memberUserVO.setMemberTagVOList(BeanUtil.copyToList(memberTagDao.selectBatchIds(memberUserVO.getMemberTags()), MemberTagVO.class));
        }
        memberUserVO.setMemberEducationalBackgroundVOList(BeanUtil.copyToList(educationalBackgroundDao.selectList(new LambdaQueryWrapper<MemberEducationalBackgroundEntity>().eq(MemberEducationalBackgroundEntity::getMemberUserId, id)), MemberEducationalBackgroundVO.class));
        return memberUserVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> idList) {
        removeByIds(idList);
    }

    @Override
    public void importByExcel(MultipartFile file) {
        String password = passwordEncoder.encode("123456");
        ExcelUtils.readAnalysis(file, MemberUserExcelVO.class, new ExcelFinishCallBack<>() {
            @Override
            public void doSaveBatch(List<MemberUserExcelVO> result) {
                ExcelUtils.parseDict(result);
                List<MemberUserEntity> userList = BeanUtil.copyToList(result.stream().filter(item -> StringUtils.isNotEmpty(item.getMobile())).toList(), MemberUserEntity.class);
                if (CollectionUtils.isNotEmpty(result)) {
                    List<String> mobileList = userList.stream().map(MemberUserEntity::getMobile).filter(org.apache.commons.lang3.StringUtils::isNotEmpty).toList();
                    if (CollectionUtils.isEmpty(mobileList)) {
                        return;
                    }
                    List<SysOrgEntity> sysOrgEntityList = sysOrgDao.selectList(new LambdaQueryWrapper<SysOrgEntity>().in(SysOrgEntity::getName, result.stream().map(MemberUserExcelVO::getOrgName).collect(Collectors.toList())));
                    Map<String, SysOrgEntity> sysOrgEntityMap;
                    if (CollectionUtils.isNotEmpty(sysOrgEntityList)) {
                        sysOrgEntityMap = sysOrgEntityList.stream().collect(Collectors.toMap(SysOrgEntity::getName, Function.identity()));
                    } else {
                        sysOrgEntityMap = null;
                    }
                    List<MemberUserEntity> needAddList = new ArrayList<>();
                    List<MemberUserEntity> memberUserEntityList = memberUserDao.selectList(new LambdaQueryWrapper<MemberUserEntity>().in(MemberUserEntity::getMobile, mobileList));
                    List<String> checkMobileList = new ArrayList<>();
                    if (CollectionUtils.isNotEmpty(memberUserEntityList)) {
                        checkMobileList.addAll(memberUserEntityList.stream().map(MemberUserEntity::getMobile).toList());
                    }
                    for (int i = 0; i < userList.size(); i++) {
                        if (ObjectUtils.isNotEmpty(userList.get(i))) {
                            MemberUserEntity item = userList.get(i);
                            item.setWhetherMember(Constant.ENABLE);
                            if (!checkMobileList.contains(item.getMobile())) {
                                item.setPassword(password);
                                needAddList.add(item);
                                checkMobileList.add(item.getMobile());
                            }
                            if (ObjectUtils.isNotEmpty(sysOrgEntityMap)) {
                                SysOrgEntity sysOrgEntity = sysOrgEntityMap.get(item.getOrgName());
                                if (ObjectUtils.isNotEmpty(sysOrgEntity)) {
                                    item.setOrgId(sysOrgEntity.getId());
                                }
                            }
                        }
                    }
                    if (CollectionUtils.isNotEmpty(needAddList)) {
                        saveBatch(needAddList);
                    }
                }
            }
        });
    }

    @Override
    public void export(String orgId) {
        LambdaQueryWrapper<MemberUserEntity> wrapper = new LambdaQueryWrapper<MemberUserEntity>().eq(MemberUserEntity::getWhetherMember, Constant.ENABLE)
                .eq(MemberUserEntity::getDeleted, false)
                .eq(MemberUserEntity::getAuditStatus, Constant.ENABLE)
                .eq(MemberUserEntity::getRemoveStatus, false);
        if (!SecurityUser.getUser().getSuperAdmin().equals(Constant.SUPER_ADMIN)) {
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(orgId)) {
                wrapper.eq(MemberUserEntity::getOrgId, orgId);
            } else {
                dataScopeWrapper(wrapper);
            }
        } else {
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(orgId)) {
                wrapper.eq(MemberUserEntity::getOrgId, orgId);
            }
        }
        List<MemberUserEntity> list = list(wrapper);
        List<MemberUserExcelVO> memberUserExcelVOList = BeanUtil.copyToList(list, MemberUserExcelVO.class);
        transService.transBatch(memberUserExcelVOList);
        // 写到浏览器打开
        ExcelUtils.excelExport(MemberUserExcelVO.class, "会员信息", null, memberUserExcelVOList);
    }

}